/**
 *    Copyright 2012 Geensoft S.A.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 **/
package ar.com.greensoft.neo.web.jsf.beans.user;

import java.io.Serializable;
import java.util.Date;
import java.util.Set;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;

import org.apache.commons.lang.math.RandomUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import ar.com.greensoft.neo.dao.DaoException;
import ar.com.greensoft.neo.dao.PersonaFisicaDao;
import ar.com.greensoft.neo.model.PersonaFisica;
import ar.com.greensoft.neo.model.constraint.CUITVerificationDigitCalulator;
import ar.com.greensoft.neo.model.references.EstadoCivil;
import ar.com.greensoft.neo.model.references.Sexo;
import ar.com.greensoft.neo.model.references.TipoDocumento;

/**
 * @author Jorge E. Villaverde
 *
 */
@Component
@RequestScoped
@ManagedBean
public class LoadDataBean implements Serializable {
    private static final long serialVersionUID = -314414475508376585L;
    private static final Logger logger = LoggerFactory.getLogger(LoadDataBean.class);
    private boolean buttonRendered = true;
    private boolean enabled = false;
    private Long startTime;
    private PersonaFisicaDataLoader loader;
    
    @Autowired
    private PersonaFisicaDao personaFisicaDao;
 
    public String startProcess() {
        setEnabled(true);
        setButtonRendered(false);
        setStartTime(new Date().getTime());
        loader = new PersonaFisicaDataLoader(personaFisicaDao, 5000);
        new Thread(loader).start();
        return null;
    }
 
    public Long getCurrentValue() {
        if (isEnabled()) {
            Long current = (long)loader.progress();
            if (current >= 100) {
                setButtonRendered(true);
            } else if (current.equals(0)) {
                return new Long(1);
            }
            return current;
        }
        if (startTime == null) {
            return Long.valueOf(-1);
        } else {
            return Long.valueOf(100);
        }
    }
 
    public boolean isEnabled() {
        return enabled;
    }
 
    public void setEnabled(boolean enabled) {
        this.enabled = enabled;
    }
 
    public Long getStartTime() {
        return startTime;
    }
 
    public void setStartTime(Long startTime) {
        this.startTime = startTime;
    }
 
    public boolean isButtonRendered() {
        return buttonRendered;
    }
 
    public void setButtonRendered(boolean buttonRendered) {
        this.buttonRendered = buttonRendered;
    }
    
	
	private class PersonaFisicaDataLoader implements Runnable{
		private final PersonaFisicaDao personaFisicaDao;
		private final int numberOfInserts;
		private int currentInsert;
		
		public PersonaFisicaDataLoader(PersonaFisicaDao personaFisicaDao, int numberOfInserts) {
			super();
			this.personaFisicaDao = personaFisicaDao;
			this.numberOfInserts = numberOfInserts;
			this.currentInsert = 0; 
		}
		
		@Override
		public void run() {
			while(currentInsert < numberOfInserts){
				try {
					insertarPersonaFisica(currentInsert);
				} catch (DaoException e) {
					logger.error(e.getMessage());
					break;
				}
				currentInsert++;
			}
		}
		
		public synchronized int progress(){
			return (int)(100 * (1.0f*currentInsert)/(1.0f*numberOfInserts));
		}		

		private void insertarPersonaFisica(int i) throws DaoException {
			PersonaFisica p = new PersonaFisica();
			
			long dni = 20000000+i;
			
			p.setTipoDocumento(TipoDocumento.DNI);
			p.setNumeroDocumento(dni);
			
			p.setSexo(RandomUtils.nextBoolean() ? Sexo.HOMBRE : Sexo.MUJER);
			p.setEstadoCivil(EstadoCivil.SOLTERO);
			p.setPrimerNombre("Nombre "+ i);
			p.setApellido1("Apellido " + i);
			p.setFechaNacimiento(new Date());
			String cuip = CUITVerificationDigitCalulator.calculateCuip(
					p.getTipoDocumento(), 
					p.getNumeroDocumento(),
					p.getSexo());
			p.setCuip(cuip);
			
			ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
			Validator validator = factory.getValidator();

			Set<ConstraintViolation<PersonaFisica>> constraintViolations = validator.validate(p);

			if(constraintViolations.size() == 0){
				personaFisicaDao.persist(p);
			}else{
				logger.info("No se puede crear " + p.getNombreApellido() + " " + constraintViolations.toString());
			}
		} 
	}
}
